//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Workflow.ComponentModel;

namespace Microsoft.Research.ScientificWorkflow.Activities
{
    [Name("FTPUpload")]
    [Description("Activity to upload a file to FTP Server.")]
    [WorkflowCategory("Web")]
    public class FTPFileDownloadActivity : Activity
    {
        #region Dependency Properties

        public static DependencyProperty FTPRequestObjectProperty = DependencyProperty.Register("FTPRequestObject",
            typeof(FtpWebRequest), typeof(FTPFileDownloadActivity));

        [RequiredInputParam]
        [Name("FTP Connection")]
        [Description("Connection Object to the FTP server.")]
        public FtpWebRequest FTPRequestObject
        {
            get
            {
                return ((FtpWebRequest)(base.GetValue(FTPFileDownloadActivity.FTPRequestObjectProperty)));
            }
            set
            {
                base.SetValue(FTPFileDownloadActivity.FTPRequestObjectProperty, value);
            }
        }

        public static DependencyProperty DownloadFolderProperty = DependencyProperty.Register("DownloadFolder",
            typeof(DirectoryInfo), typeof(FTPFileDownloadActivity));

        [RequiredInputParam]
        [Name("Directory")]
        [Description("Folder where the file is to be downloaded.")]
        public DirectoryInfo DownloadFolder
        {
            get
            {
                return ((DirectoryInfo)(base.GetValue(FTPFileDownloadActivity.DownloadFolderProperty)));
            }
            set
            {
                base.SetValue(FTPFileDownloadActivity.DownloadFolderProperty, value);
            }
        }

        public static DependencyProperty FileNameProperty = DependencyProperty.Register("FileName",
            typeof(string), typeof(FTPFileDownloadActivity));

        [RequiredInputParam]
        [Name("File Name")]
        [Description("Name for the file to be downloaded.")]
        public string FileName
        {
            get
            {
                return ((string)(base.GetValue(FTPFileDownloadActivity.FileNameProperty)));
            }
            set
            {
                base.SetValue(FTPFileDownloadActivity.FileNameProperty, value);
            }
        }

        #endregion

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            try
            {
                FileStream outputStream = new FileStream(this.DownloadFolder.Name + "\\" +
                   this.FileName, FileMode.Create);

                this.FTPRequestObject.Method = WebRequestMethods.Ftp.DownloadFile;
                this.FTPRequestObject.UseBinary = true;

                FtpWebResponse response = (FtpWebResponse)this.FTPRequestObject.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];

                readCount = ftpStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    outputStream.Write(buffer, 0, readCount);
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }

                ftpStream.Close();
                outputStream.Close();
                response.Close();
            }
            catch (Exception)
            {
                return ActivityExecutionStatus.Faulting;
            }

            return ActivityExecutionStatus.Closed;
        }
    }
}
